package com.kevin.service.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kevin.common.enums.ScheduleStatusEnum;
import com.kevin.service.entity.ScheduleJob;
import com.kevin.service.mapper.ScheduleJobMapper;
import com.kevin.service.service.ScheduleJobService;
import com.kevin.service.util.job.ScheduleUtils;
import lombok.RequiredArgsConstructor;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 定时任务(ScheduleJob)表服务实现类
 *
 * @author makejava
 * @since 2023-03-27 16:03:24
 */
@Service
@RequiredArgsConstructor
public class ScheduleJobServiceImpl extends ServiceImpl<ScheduleJobMapper, ScheduleJob> implements ScheduleJobService {
    private final Scheduler scheduler;
    private static final String profile = SpringUtil.getActiveProfile();

    /**
     * 启动项目时，初始化定时器
     */
//    @PostConstruct
    public void init() throws SchedulerException {
        // 异步不阻塞主线程，不会 增加启动用时
        CompletableFuture.supplyAsync(() -> {
            try {
                scheduler.clear();
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
            List<ScheduleJob> scheduleJobList = baseMapper.selectList(null);
            for (ScheduleJob scheduleJob : scheduleJobList) {
                ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
                // 仅在启动时检查
                if (StrUtil.contains(scheduleJob.getExcludeProfiles(), profile)) {
                    // 当前环境禁止,暂停job
                    ScheduleUtils.pauseJob(scheduler, scheduleJob);
                    updateById(ScheduleJob.builder().id(scheduleJob.getId()).status(0).build());
                }
            }
            return null;
        });
    }

    @Override
    public void saveP(ScheduleJob vo) {

        vo.setStatus(ScheduleStatusEnum.PAUSE.getValue());
        if (baseMapper.insert(vo) > 0) {
            ScheduleUtils.createScheduleJob(scheduler, vo);
        }
    }

    @Override
    public void update(ScheduleJob entity) {
        // 更新定时任务
        if (updateById(entity)) {
            ScheduleJob scheduleJob = getById(entity.getId());
            ScheduleUtils.updateSchedulerJob(scheduler, scheduleJob);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        for (Long id : idList) {
            ScheduleJob scheduleJob = getById(id);

            // 删除定时任务
            if (removeById(id)) {
                ScheduleUtils.deleteScheduleJob(scheduler, scheduleJob);
            }
        }
    }

    @Override
    public void run(ScheduleJob vo) {
        ScheduleJob scheduleJob = getById(vo.getId());
        if (scheduleJob == null) {
            return;
        }

        ScheduleUtils.run(scheduler, scheduleJob);
    }

    @Override
    public void changeStatus(ScheduleJob vo) {
        ScheduleJob scheduleJob = getById(vo.getId());
        if (scheduleJob == null) {
            return;
        }

        // 更新数据
        scheduleJob.setStatus(vo.getStatus());
        updateById(scheduleJob);

        if (ScheduleStatusEnum.PAUSE.getValue() == vo.getStatus()) {
            ScheduleUtils.pauseJob(scheduler, scheduleJob);
        } else if (ScheduleStatusEnum.NORMAL.getValue() == vo.getStatus()) {
            ScheduleUtils.resumeJob(scheduler, scheduleJob);
        }
    }
}

